package com.ruoyi.web.controller.customer;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.api.domain.AppManage;
import com.ruoyi.api.service.IAppManageService;
import com.ruoyi.api.service.IApiManageService;
import com.ruoyi.api.domain.ApiManage;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.quartz.util.CronUtils;
import com.ruoyi.quartz.util.ScheduleUtils;

/**
 * 应用管理Controller
 * 
 * @author ruoyi
 * @date 2025-08-06
 */
@RestController
@RequestMapping("/customer/appManage")
public class CustomerAppManageController extends BaseController
{
    private static final Logger logger = LoggerFactory.getLogger(CustomerAppManageController.class);
    
    @Autowired
    private IAppManageService appManageService;
    
    @Autowired
    private IApiManageService apiManageService;
    
    @Autowired
    private ISysJobService jobService;

    /**
     * 查询应用管理列表
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @GetMapping("/list")
    public TableDataInfo list(AppManage appManage)
    {
        startPage();
        appManage.setCreateBy(getUsername());
        appManage.setAppUser(getUsername());
        List<AppManage> list = appManageService.selectAppManageList(appManage);
        return getDataTable(list);
    }

    /**
     * 导出应用管理列表
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @Log(title = "应用管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AppManage appManage)
    {
        List<AppManage> list = appManageService.selectAppManageList(appManage);
        ExcelUtil<AppManage> util = new ExcelUtil<AppManage>(AppManage.class);
        util.exportExcel(response, list, "应用管理数据");
    }

    /**
     * 获取应用管理详细信息
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @GetMapping(value = "/{appId}")
    public AjaxResult getInfo(@PathVariable("appId") Long appId)
    {
        return success(appManageService.selectAppManageByAppId(appId));
    }

    /**
     * 新增应用管理
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @Log(title = "应用管理", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional
    public AjaxResult add(@RequestBody CreateAppWithTaskRequest request)
    {
        try {
            // 设置应用基本信息
            AppManage appManage = request.getAppManage();
            appManage.setCreateBy(getUsername());
            appManage.setAppUser(getUsername());
            
            // 创建应用
            int result = appManageService.insertAppManage(appManage);
            if (result <= 0) {
                return error("应用创建失败");
            }
            
            // 如果应用类型包含定时执行，且提供了定时任务配置，则创建定时任务
            if (("定时".equals(appManage.getAppType()) || "全部".equals(appManage.getAppType())) 
                && request.getTaskConfig() != null) {
                
                TaskConfig taskConfig = request.getTaskConfig();
                
                // 验证定时任务参数
                if (StringUtils.isEmpty(taskConfig.getCronExpression())) {
                    return error("定时任务Cron表达式不能为空");
                }
                
                if (!CronUtils.isValid(taskConfig.getCronExpression())) {
                    return error("Cron表达式格式不正确");
                }
                
                // 获取API服务信息构建调用URL
                ApiManage apiInfo = apiManageService.selectApiManageByApiId(appManage.getApiId());
                if (apiInfo == null) {
                    return error("关联的API服务不存在");
                }
                
                // 创建定时任务，所有参数都在后端自动生成
                SysJob job = new SysJob();
                job.setJobName("app_" + appManage.getAppId() + "_" + getUsername() + "_task");  // 任务名称：app_{appId}_{username}_task
                job.setJobGroup("customer_app_group");  // 任务组：customer_app_group
                job.setInvokeTarget("customerTask.executeAppTask('" + appManage.getAppId() + "')");  // 调用目标：customerTask.executeAppTask('appId')
                job.setCronExpression(taskConfig.getCronExpression());
                job.setMisfirePolicy("1");  // 默认立即执行
                job.setConcurrent("1");  // 默认禁止并发
                job.setStatus("0");  // 默认直接启动状态
                job.setCreateBy(getUsername());
                job.setRemark(StringUtils.isNotEmpty(taskConfig.getRemark()) ? taskConfig.getRemark() : "应用[" + appManage.getAppName() + "]的定时任务，创建人：" + getUsername());
                
                // 检查调用目标是否在白名单内
                if (!ScheduleUtils.whiteList(job.getInvokeTarget())) {
                    return error("创建定时任务失败，目标字符串不在白名单内");
                }
                
                int jobResult = jobService.insertJob(job);
                if (jobResult <= 0) {
                    return error("定时任务创建失败");
                }
            }
            
            return success("应用创建成功");
            
        } catch (SchedulerException | TaskException e) {
            return error("创建定时任务失败：" + e.getMessage());
        } catch (Exception e) {
            return error("应用创建失败：" + e.getMessage());
        }
    }

    /**
     * 修改应用管理
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @Log(title = "应用管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AppManage appManage)
    {
        return toAjax(appManageService.updateAppManage(appManage));
    }

    /**
     * 删除应用管理
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @Log(title = "应用管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{appIds}")
    public AjaxResult remove(@PathVariable Long[] appIds)
    {
        try {
            // 删除应用前，先删除相关的定时任务
            for (Long appId : appIds) {
                // 获取应用信息
                AppManage appManage = appManageService.selectAppManageByAppId(appId);
                if (appManage != null) {
                    // 构建定时任务名称模式：app_{appId}_{username}_task
                    String jobNamePattern = "app_" + appId + "_" + appManage.getCreateBy() + "_task";
                    
                    // 查询并删除相关的定时任务
                    SysJob queryJob = new SysJob();
                    queryJob.setJobName(jobNamePattern);
                    queryJob.setJobGroup("customer_app_group");
                    
                    List<SysJob> jobs = jobService.selectJobList(queryJob);
                    for (SysJob job : jobs) {
                        try {
                            jobService.deleteJob(job);
                        } catch (SchedulerException e) {
                            logger.warn("删除定时任务失败，任务ID: " + job.getJobId() + ", 错误: " + e.getMessage());
                        }
                    }
                }
            }
            
            // 删除应用
            return toAjax(appManageService.deleteAppManageByAppIds(appIds));
            
        } catch (Exception e) {
            return error("删除应用失败：" + e.getMessage());
        }
    }

    /**
     * 生成新的应用密钥
     */
    @PreAuthorize("@ss.hasRole('customer')")
    @Log(title = "生成应用密钥", businessType = BusinessType.UPDATE)
    @PutMapping("/regenerateKey/{appId}")
    public AjaxResult regenerateSecretKey(@PathVariable Long appId)
    {
        // 验证应用是否属于当前用户
        AppManage existingApp = appManageService.selectAppManageByAppId(appId);
        if (existingApp == null || !getUsername().equals(existingApp.getCreateBy())) {
            return error("无权限操作此应用");
        }
        
        int result = appManageService.regenerateSecretKey(appId);
        if (result > 0) {
            // 返回更新后的应用信息，包含新的密钥
            AppManage appManage = appManageService.selectAppManageByAppId(appId);
            AjaxResult ajaxResult = success(appManage);
            ajaxResult.put("msg", "密钥生成成功");
            return ajaxResult;
        }
        return error("密钥生成失败");
    }
    
    /**
     * 创建应用请求对象（包含定时任务配置）
     */
    public static class CreateAppWithTaskRequest {
        private AppManage appManage;
        private TaskConfig taskConfig;
        
        public AppManage getAppManage() {
            return appManage;
        }
        
        public void setAppManage(AppManage appManage) {
            this.appManage = appManage;
        }
        
        public TaskConfig getTaskConfig() {
            return taskConfig;
        }
        
        public void setTaskConfig(TaskConfig taskConfig) {
            this.taskConfig = taskConfig;
        }
    }
    
    /**
     * 定时任务配置
     */
    public static class TaskConfig {
        private String cronExpression;
        private String remark;
        
        public String getCronExpression() {
            return cronExpression;
        }
        
        public void setCronExpression(String cronExpression) {
            this.cronExpression = cronExpression;
        }
        
        public String getRemark() {
            return remark;
        }
        
        public void setRemark(String remark) {
            this.remark = remark;
        }
    }
}